//
// Created by LiuYou on 2021/7/23.
//

#ifndef MODERNCPP_HASPTRLIKEPTRUSEPOINTER_HPP
#define MODERNCPP_HASPTRLIKEPTRUSEPOINTER_HPP


#include <string>
#include <ostream>

namespace ResourceManagement {
    class HasPtrLikePtrUsePointer {
        //  开始
        // 较为新式的copy assignment operator的写法, 以后就使用这种写法吧。
    public:
        friend void swap(HasPtrLikePtrUsePointer& lhs, HasPtrLikePtrUsePointer& rhs) {
            std::swap( lhs.ptrString, rhs.ptrString );
            std::swap( lhs.defaultValue, rhs.defaultValue );
            std::swap( lhs.referenceCount, rhs.referenceCount );
        }

        /// \brief 拷贝并交换这项技术的有趣指出是它自动处理了自我赋值情况且天然就是异常安全的。
        /// \param rhs
        /// \return
        HasPtrLikePtrUsePointer& operator=(HasPtrLikePtrUsePointer rhs);

        // 结束

    public:
        size_t* getReferenceCount() const;

    public:
        friend std::ostream& operator<<(std::ostream& os, const HasPtrLikePtrUsePointer& ptr) {
            os << "{" << "ptrString: " << ptr.ptrString
               << ", *ptrString: " << "\"" << *ptr.ptrString << "\""
               << ", defaultValue: " << ptr.defaultValue
               << ", referenceCount: " << ptr.referenceCount
               << ", *referenceCount: " << *ptr.referenceCount << "}";
            return os;
        }

    public:
//        HasPtrLikePtrUsePointer(std::string* ptrString, int defaultValue, size_t* referenceCount);

        explicit HasPtrLikePtrUsePointer(const std::string& hasPtrLikePtr = std::string());

        virtual ~HasPtrLikePtrUsePointer();

        HasPtrLikePtrUsePointer(const HasPtrLikePtrUsePointer& rhs);

        /// \brief 较为传统的写法。
//        HasPtrLikePtrUsePointer& operator=(const HasPtrLikePtrUsePointer& rhs);

    private:
        std::string* ptrString;
        int defaultValue;
        std::size_t* referenceCount;

    };

}


#endif //MODERNCPP_HASPTRLIKEPTRUSEPOINTER_HPP
